package no.ntnu.fp.su;

import java.sql.Timestamp;
import java.util.ArrayList;

import no.ntnu.fp.db.Database;

public class LogEntry {

	private ArrayList<Comment> comments;
	private Status status;
	private double r;
	private double deltaR;
	private double p;
	private double t;
	private int wellID;
	private Timestamp time;
	private Database db;

	// private boolean read;

	/**
	 * new LogEntry
	 */
	public LogEntry() {
		// read = false;
		time = new Timestamp(System.currentTimeMillis());
	}

	/**
	 * 
	 * new LogEntry
	 * 
	 * @param wellID
	 * @param status
	 * @param r
	 * @param dr
	 * @param t
	 * @param p
	 * @param time
	 */
	public LogEntry(int wellID, Status status, double r, double dr, double t,
			double p, Timestamp time) {

		if (time == null)
			this.time = new Timestamp(System.currentTimeMillis());
		else
			this.time = time;
		this.r = r;
		this.p = p;
		this.t = t;
		deltaR = dr;
		this.status = status;
		this.wellID = wellID;
		comments = new ArrayList<Comment>();
		// read = false;
	}

	/**
	 * retrieve comments
	 * 
	 * @return {@link ArrayList<Comment>}
	 */
	public ArrayList<Comment> getComments() {
		return comments;
	}

	/**
	 * 
	 * @return number of comments
	 */
	public int getCommentSize() {
		return comments.size();
	}

	/**
	 * 
	 * @return well status of the entry
	 */
	public Status getStatus() {
		return status;
	}

	/**
	 * 
	 * @return
	 */
	public double getR() {
		return r;
	}

	/**
	 * 
	 * @return
	 */
	public double getDeltaR() {
		return deltaR;
	}

	/**
	 * 
	 * @return
	 */
	public double getP() {
		return p;
	}

	/**
	 * 
	 * @return
	 */
	public double getT() {
		return t;
	}

	/**
	 * 
	 * @return
	 */
	public int getWellID() {
		return wellID;
	}

	/**
	 * 
	 * @return
	 */
	public Timestamp getTime() {
		return time;
	}

	/**
	 * Writes the {@link LogEntry} to the {@link Database}
	 * 
	 * @param {@link Database}<br>
	 *        The database to be written to, expected to be connected
	 * 
	 */
	public void writeToDb(Database db) {

		String statement = "insert into welllog values(" + getWellID() + ",\""
				+ getTime().toString() + "\"," + getR() + "," + getDeltaR()
				+ "," + getT() + "," + getP() + "," + "\"" + getStatus() + "\""
				+ ")";
		db.execute(statement);
	}

	/**
	 * add comment to this logentry and save to DB
	 * 
	 * @param {@link Comment}
	 */
	public void newComment(String comment) {
		// if (!read) {
		// throw new NullPointerException("comments not read from db yet");
		// }
		// TODO new check
		int id = newId();
		comments.add(new Comment(id, comment));
		db.connect();
		db.execute("insert into comments values(" + wellID + ",\""
				+ getTime().toString() + "\"," + id + "," + "\"" + comment
				+ "\")");
		db.disconnect();
	}

	/**
	 * Add comment to this {@link LogEntry}, used when loading from DB
	 * 
	 * @param {@link Integer} id
	 * @param {@link String} Content
	 */
	public void addComment(int id, String comment) {
		comments.add(new Comment(id, comment));
	}

	/**
	 * Get a new ID for creating new {@link Comment}s, to avoid duplicate IDs on
	 * same {@link Timestamp}
	 * 
	 * @return {@link Integer} id
	 */
	private synchronized int newId() {
		boolean free = false;
		for (int i = 0; i < 1000; i++) {
			free = true;
			for (Comment c : comments) {
				if (c.getCommentID() == i) {
					free = false;
					break;
				}
			}
			if (free)
				return i;
		}
		return 0;
	}

	/**
	 * delete comment locally and in the DB
	 * 
	 * @param {@link Integer} index
	 */
	public void deleteComment(int index) {
		db.connect();
		db.execute("delete from comments where wellid=" + wellID
				+ " and commentid=" + index + ";");
		System.out.println("deleted event " + index);
		db.disconnect();

		comments.remove(getCommentID(index));
	}

	/**
	 * Get internal index of a Comment with given index
	 * 
	 * @param {@link Integer} comment id
	 * @return {@link Integer} internal index
	 */
	private int getCommentID(int index) {
		for (Comment c : comments) {
			if (c.getCommentID() == index) {
				return comments.indexOf(c);
			}
		}
		return 0;
	}

	/**
	 * link the db
	 * 
	 * @param {@link Database} db
	 */
	public void addDB(Database db) {
		this.db = db;

	}

}
